﻿using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json;

namespace LinqToOwin.Web.Labs.Data
{
  // https://dev.twitter.com/docs/api/1.1/get/search/tweets
  public static class TwitterClient
  {
    private static readonly string query = HttpUtility.UrlEncode("#ReactiveX OR #ReactiveExtensions OR #RxNET OR #RxJS OR #RxJava OR #RxScala");
    private static readonly Uri serviceUrl = new Uri("https://api.twitter.com/1.1/search/tweets.json?q=" + query + "&geocode=", UriKind.Absolute);
    private static readonly Uri authServiceUrl = new Uri("https://api.twitter.com/oauth2/token", UriKind.Absolute);
    private const string radius = "20mi";

    public static async Task<IEnumerable<Tweet>> GetTweets(decimal latitude, decimal longitude)
    {
      var url = serviceUrl.AbsoluteUri + latitude + ',' + longitude + ',' + radius;

      using (var client = new HttpClient())
      {
        var token = await Authenticate().ConfigureAwait(false);

        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);

        var json = await client.GetStringAsync(url).ConfigureAwait(false);

        return Tweet.Parse(json);
      }
    }

    // https://dev.twitter.com/docs/auth/application-only-auth
    private static async Task<string> Authenticate()
    {
      var credentials = "TvVwONKaZorsOwrzfGBfvu0kC:ZvCzXDFQbkrcckpiESSwnTT0MlVjEIuVp2ObMBt4Aj2aOWSal9";
      var base64Credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials), Base64FormattingOptions.None);

      using (var client = new HttpClient())
      {
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Credentials);

        var response = await client.PostAsync(authServiceUrl, new FormUrlEncodedContent(new Dictionary<string, string>()
          {
            { "grant_type", "client_credentials" }
          }))
          .ConfigureAwait(false);

        var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

        response.EnsureSuccessStatusCode();

        var result = JsonConvert.DeserializeAnonymousType(json, new { token_type = string.Empty, access_token = string.Empty });

        if (result.token_type != "bearer")
        {
          throw new SecurityException("Twitter OAuth did not return token_type of 'bearer'.");
        }

        return result.access_token;
      }
    }
  }
}